import { Injectable } from '@nestjs/common';
import { Permission } from './permission.model';
import { InjectModel } from '@nestjs/sequelize';
import type { CreatePermissionDto as CreateDto } from './dtos/create.dto';
import type { Includeable, Order, WhereOptions } from 'sequelize';
import { RuntimeException } from 'src/exceptions/runtime.exception';
import { UpdatePermissionDto as UpdateDto } from './dtos/update.dto';

@Injectable()
export class PermissionService {
  constructor(
    @InjectModel(Permission) private permissionModel: typeof Permission,
  ) {}

  async findAll(
    limit: number,
    page: number,
    where: WhereOptions,
    order: Order,
  ): Promise<{ total: number; data: Permission[] }> {
    const total = await this.permissionModel.count({ where });
    const data = await this.permissionModel.findAll({
      offset: (page - 1) * limit,
      where,
      limit,
      // order: [["created_at", sort]],
      order,
      // 返回原始对象，而不是模型对象，节约性能
      raw: true,
    });
    return {
      total,
      data,
    };
  }

  async findByPk(id: string): Promise<Permission> {
    const permission = await this.permissionModel.findByPk(id);
    if (!permission) {
      throw new RuntimeException('权限不存在', 1);
    }
    return permission;
  }

  async findOneWith(
    where: Record<string, string>,
    ...include: Includeable[]
  ): Promise<Permission> {
    return this.permissionModel.findOne({
      where,
      include,
    });
  }

  async create(data: CreateDto) {
    return await this.permissionModel.create({ ...data });
  }

  async update(id: string, data: UpdateDto) {
    const permission = await this.findByPk(id);
    // 不允许修改的字段
    const notAllow = [
      'id',
      'code',
      'created_at',
      'updated_at',
      'deleted_at',
    ].find((key) => data[key]);
    if (notAllow) {
      throw new RuntimeException(`不允许修改${notAllow}`, 2);
    }

    permission.set(data);
    return await permission.save();
  }

  async remove(id: string): Promise<boolean> {
    const permission = await this.findByPk(id);

    await permission.destroy();

    return true;
  }

  async removeBatch(ids: string[]): Promise<boolean> {
    await this.permissionModel.destroy({
      where: {
        id: ids,
      },
    });

    return true;
  }
}
